package de.lindenvalley.ergo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;

import util.AnotherFont;


import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.RelativeLayout.LayoutParams;

public class CameraActivity extends Activity implements SurfaceHolder.Callback, SensorEventListener{
	
	private final String TAG = getClass().getSimpleName();
	private Camera camera;
	private SurfaceView surfaceView;
	private SurfaceHolder surfaceHolder;
	public static final String FILE_NAME = "ergo_photo";
	private File FILE_PATH;
	private boolean isRotate;
	protected Uri photoUri;
	private ImageView iv;
	private TextView tv;
	private int halfWidth;
	private SensorManager mSensorManager;
    private Sensor sensorAccelerometer;
    private Sensor sensorMagneticField;
    
    private float[] valuesAccelerometer;
    private float[] valuesMagneticField;
     
    private float[] matrixR;
    private float[] matrixI;
    private float[] matrixValues;

    


    
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        valuesAccelerometer = new float[3];
        valuesMagneticField = new float[3];
         
        matrixR = new float[9];
        matrixI = new float[9];
        matrixValues = new float[3];
        
        FILE_PATH =  new File(getFilesDir(), FILE_NAME + System.currentTimeMillis() + ".jpg");
        
        setContentView(R.layout.camera);
        
        AnotherFont.findTypeface((ViewGroup)getWindow().getDecorView());
        
        surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        ImageView takePicture = (ImageView) findViewById(R.id.imageTakePicture);
        takePicture.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Log.i(TAG, "onClick()...");
				camera.takePicture(null, null, mPictureCallback);
				
			}
		});
        
        TextView messageView = (TextView) findViewById(R.id.textViewMessage);
        messageView.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				v.setVisibility(View.GONE);
			}
		});
        
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        sensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorMagneticField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        iv = (ImageView) findViewById(R.id.imageSquare);
        tv = (TextView) findViewById(R.id.textView1);
        halfWidth = getWindow().getWindowManager().getDefaultDisplay().getWidth()/2;

    }
	
	

	/* (non-Javadoc)
	 * @see android.app.Activity#onPause()
	 */
	@Override
	protected void onPause() {
		Log.i(TAG, "onPause()...");
		mSensorManager.unregisterListener(this, sensorAccelerometer);
		mSensorManager.unregisterListener(this, sensorMagneticField);
		super.onPause();
		if (camera != null) {
			camera.stopPreview();
			camera.setPreviewCallback(null);
			camera.release();
			camera = null;
		}
		
	}



	/* (non-Javadoc)
	 * @see android.app.Activity#onResume()
	 */
	@Override
	protected void onResume() {
		Log.i(TAG, "onResume()...");
		super.onResume();
		try{
			camera = Camera.open();
		} catch (Exception ex){
			ex.printStackTrace();
			finish();
		}
		mSensorManager.registerListener(this, sensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
		mSensorManager.registerListener(this, sensorMagneticField, SensorManager.SENSOR_DELAY_NORMAL);
	}



	protected void setDisplayOrientation(Camera camera, int angle){
        Method downPolymorphic;
        try
        {
            downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
            if (downPolymorphic != null)
                downPolymorphic.invoke(camera, new Object[] { angle });
        }
        catch (Exception e1)
        {
        }
    }

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if (camera != null) {
			try {
				camera.setPreviewDisplay(surfaceHolder);

				Parameters parameters = camera.getParameters();
				Size previewSize = parameters.getPreviewSize();
				if (previewSize.width > previewSize.height){
					setDisplayOrientation(camera, 90);
					isRotate = true;
				}
				
				camera.startPreview();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		Log.i(TAG, "surfaceDestroyed()...");
		if (camera != null) {
			camera.stopPreview();
			camera.setPreviewCallback(null);
			camera.release();
			camera = null;
	    }

		
	}
	
	Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
		
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			Log.i(TAG, "onPictureTaken()...");
			Intent intent = new Intent(CameraActivity.this, ResultActivity.class);
			FileOutputStream outStream = null;
            try{
//                outStream = new FileOutputStream(CameraActivity.this.getFilesDir() + FILE_NAME);

                if (isRotate){
	                BitmapFactory.Options opt = new BitmapFactory.Options();
	                opt.inSampleSize = 2;
	                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);
	                Matrix matrix = new Matrix();
	                matrix.postRotate(90);
	                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
	                outStream = new FileOutputStream(FILE_PATH);
	                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
	                outStream.flush();
	                outStream.close();
	                bitmap.recycle();
	                bitmap = null;

                } else {
                	
            	outStream = new FileOutputStream(FILE_PATH);
                outStream.write(data);
                outStream.close();
                }
				
//				String path = FILE_PATH.toString().toLowerCase();
//		        String name = FILE_PATH.getName().toLowerCase();
//
//
//		         ContentValues values = new ContentValues(); 
//		         values.put(Media.TITLE, "Image"); 
//		         values.put(Images.Media.BUCKET_ID, path.hashCode());
//		         values.put(Images.Media.BUCKET_DISPLAY_NAME,name);
//
//		         values.put(Images.Media.MIME_TYPE, "image/jpeg");
//		         values.put(Media.DESCRIPTION, "Image capture by camera");
//		        values.put(Media.DATA, FILE_PATH.getAbsolutePath());
		        try{
//			        photoUri = getContentResolver().insert( Media.EXTERNAL_CONTENT_URI , values);
			        intent.putExtra("file", FILE_PATH.getAbsolutePath());
		        } catch (Exception ex){
		        	ex.printStackTrace();
		        }
                
            }catch(FileNotFoundException e){
            	e.printStackTrace();
            } catch (IOException e) {
            	e.printStackTrace();
            }
            
			startActivity(intent);
			finish();
		}
	};

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void onSensorChanged(SensorEvent event) {
		
//		float angle = 0;
//		if (android.os.Build.VERSION.SDK_INT <= 10 )
//			angle = event.values[2];
//		else
//			angle = event.values[1];
//		
//        RelativeLayout.LayoutParams lp = (LayoutParams) iv.getLayoutParams();
//        int barWidth = iv.getWidth()/2;
//        lp.rightMargin = (int) (halfWidth + (halfWidth * angle / 180)) - barWidth;
//        iv.requestLayout();
		
		switch(event.sensor.getType()){
		  case Sensor.TYPE_ACCELEROMETER:
		   for(int i =0; i < 3; i++){
		    valuesAccelerometer[i] = event.values[i];
		   }
		   break;
		  case Sensor.TYPE_MAGNETIC_FIELD:
		   for(int i =0; i < 3; i++){
		    valuesMagneticField[i] = event.values[i];
		   }
		   break;
		  }
		   
		  boolean success = SensorManager.getRotationMatrix(
		       matrixR, 
		       matrixI, 
		       valuesAccelerometer, 
		       valuesMagneticField);
		   
		  if(success){
		   SensorManager.getOrientation(matrixR, matrixValues);
		    
//		   double azimuth = Math.toDegrees(matrixValues[0]);
		   double pitch = Math.toDegrees(matrixValues[1]);
		   double roll = Math.toDegrees(matrixValues[2]);
		   
		   RelativeLayout.LayoutParams lp = (LayoutParams) iv.getLayoutParams();
	       int barWidth = iv.getWidth()/2;
		   
			float angle = 0;
			int barValue;
			if (android.os.Build.VERSION.SDK_INT <= 10 ){
				angle = (float) roll;
				barValue = barWidth;
			} else {
				angle = (float) pitch;
				barValue = barWidth * 2;
			}
	        
	        lp.rightMargin = (int) (halfWidth + (halfWidth * angle / 90)) - barValue;
	        iv.requestLayout();

		    
//		   readingAzimuth.setText("Azimuth: " + String.valueOf(azimuth));
//		   readingPitch.setText("Pitch: " + String.valueOf(pitch));
//		   readingRoll.setText("Roll: " + String.valueOf(roll));
//		  }
		   
		 }
		
			
		
	}

}
